/**
 * 批量重命名 key 的通用函数
 *
 * let data = { name: "张三", city: "北京", age: 25 }
 * let keyMap = { city: "address", age: "userAge" }
 *
 * let result = renameKeys(data, keyMap)
 * { name: "张三", address: "北京", userAge: 25 }
 * */
export function renameKeys(obj, keyMap) {
    return Object.fromEntries(
        Object.entries(obj).map(([key, value]) => {
            return [keyMap[key] || key, value]
        })
    )
}

/**
 * Fisher-Yates 洗牌算法（原地修改)
 * 打乱数组的顺序
 * */
export function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        // 生成一个从 0 到 i 的随机索引
        const j = Math.floor(Math.random() * (i + 1));
        // 交换元素 array[i] 和 array[j]
        [array[i], array[j]] = [array[j], array[i]];
    }
    return array;
}

// 打乱对象属性顺序的函数
export function shuffleObject(obj) {
    // 提取对象的所有键
    const keys = Object.keys(obj);
    // 打乱键的顺序
    const shuffledKeys = shuffleArray(keys);
    // 根据打乱的键重新构建对象
    const shuffledObj = {};
    shuffledKeys.forEach(key => {
        shuffledObj[key] = obj[key];
    });
    return shuffledObj;
}

export function shuffleArrayLength(array,length) {
    for (let i = array.length - 1; i > 0; i--) {
        // 生成一个从 0 到 i 的随机索引
        const j = Math.floor(Math.random() * (i + 1));
        // 交换元素 array[i] 和 array[j]
        [array[i], array[j]] = [array[j], array[i]];
    }
    return array.slice(0, length);
}

/**
 * 批量重命名 key
 * 可传入数组
 * */
export function renameArrayKeys(objArray, keyMap) {
    let newArray = []
    for (let obj in objArray) {
        let entries = Object.fromEntries(
            Object.entries(objArray[obj]).map(([key, value]) => {
                return [keyMap[key] || key, value]
            })
        );
        newArray.push(entries)
    }
    return newArray
}

/**
 * 判断对象b是否是对象a的局部匹配（b的所有属性在a中存在且值相等）
 * @param {Object} a - 被检查的对象
 * @param {Object} b - 局部模式对象（需要匹配的部分）
 * @returns {boolean} 是否局部相等
 */
export function isPartialEqual(a, b) {
    // 如果b是基本类型，直接比较值
    if (typeof b !== 'object' || b === null) {
        return a === b;
    }

    // 如果a不是对象或为null，而b是对象，则不匹配
    if (typeof a !== 'object' || a === null) {
        return false;
    }

    // 数组的局部匹配：b的每个元素都要在a中按顺序存在
    if (Array.isArray(b)) {
        if (!Array.isArray(a)) return false;

        // b的长度不能大于a
        if (b.length > a.length) return false;

        // 逐个元素比较
        return b.every((item, index) => isPartialEqual(a[index], item));
    }

    // 对象的局部匹配：b的每个属性都要在a中存在且值匹配
    return Object.keys(b).every(key => {
        // 检查a是否有该属性
        if (!a.hasOwnProperty(key)) return false;

        // 递归比较属性值
        return isPartialEqual(a[key], b[key]);
    });
}

// 示例用法
const objA = {
    name: '张三',
    age: 25,
    address: {
        city: '北京',
        district: '朝阳区',
        street: '建国路'
    },
    hobbies: ['读书', '运动', '编程']
};

// 局部匹配的情况
const objB = {
    name: '张三',
    address: {
        city: '北京'
    },
    hobbies: ['读书']
};

// console.log(isPartialEqual(objA, objB)); // 输出: true

// 不匹配的情况（属性值不同）
const objC = {
    name: '李四',
    address: {
        city: '北京'
    }
};

// console.log(isPartialEqual(objA, objC)); // 输出: false

// 不匹配的情况（b有a没有的属性）
const objD = {
    name: '张三',
    gender: '男' // objA没有gender属性
};

// console.log(isPartialEqual(objA, objD)); // 输出: false
